//#define _GNU_SOURCE
#include "Request.h"
#include "TcpConnection.h"






Request::Request()
{
    reset();
}

Request::~Request()
{
}

void Request::reset()
{
    m_chinese = m_english = m_uni = 0;
    m_id=m_method = m_name = m_job = m_passwd = m_account = "";
    
}






bool Request::parseRequest(Buffer* readBuf, Response* response, Buffer* sendBuf, int socket,MySqlConn *mysql)
{

    //解析数据
    Value root;
    readBuf->parseToValue(root);
    m_method = root["method"].asString();
    m_name = root["name"].asString();
    m_job = root["job"].asString();
    m_passwd = root["passwd"].asString();
    m_account = root["account"].asString();
    m_id = root["id"].asString();
    m_chinese = root["chinese"].asInt();
    m_math = root["math"].asInt();
    m_uni = root["uni"].asInt();
    m_english = root["english"].asInt();
    readBuf->reset();


        
    // 1. 根据解析出的原始数据, 对客户端的请求做出处理
    processRequest(response,mysql);
    // 2. 组织响应数据并发送给客户端
    response->prepareMsg(sendBuf, socket);
        
    return true;
}

bool Request::processRequest(Response* response,MySqlConn*mysql)
{
    if (m_method == "REGISTER") {
        if(isRepeate(mysql)) {
            response->setStatusCode(StatusCode::Repeat);
            return false;
        }
        char* tmp=(char*)calloc(1000,1);
         sprintf(tmp, "insert into admini (name,job,account,passwd) values ('%s','normal','%s','%s');",
            m_name.c_str(),  m_account.c_str(), m_passwd.c_str());
        string str(tmp);
       int ret= mysql->update(str);
     if (!ret) {
         response->setStatusCode(StatusCode::Failure);
         return false;

     }
        response->setStatusCode(StatusCode::OK);
        return true;
    }
    else {

        if (!isUser(mysql)) {
            response->setStatusCode(StatusCode::WrongPassword);
            return false;
        }
        else if(m_method=="GETNUM") {
            char* tmp=(char*)calloc(1000,1);
            sprintf(tmp, "select count(*) from data;");
            string str(tmp);
            if(!mysql->query(str)) {
                response->setStatusCode(StatusCode::Failure);
                return false;
            }
            mysql->next();

            //用json记录返回数据
            Value data=mysql->value(0);
            FastWriter writer;
            str = writer.write(data);
            response->setData(str);
            response->setStatusCode(StatusCode::OK);
            return true;

        }
        else if (m_method == "GET") {

            char* tmp=(char*)calloc(1000,1);
             sprintf(tmp, "select name,id,chinese,math,english,uni,total,myrank from data where id='%s';", m_id.c_str());
            string str(tmp);
            if(!mysql->query(str)) {
                response->setStatusCode(StatusCode::Failure);
                return false;
            }
            if(!mysql->next()) {
                response->setStatusCode(StatusCode::Failure);
                return false;
            }

            //用json记录返回数据
            Value data;
            data["name"] = mysql->value(0);
            data["id"] = mysql->value(1);
            data["chinese"] = stoi(mysql->value(2));
            data["math"] = stoi(mysql->value(3));
            data["english"] = stoi(mysql->value(4));
            data["uni"] = stoi(mysql->value(5));
            data["total"] = stoi(mysql->value(6));
            data["rank"] = stoi(mysql->value(7));
            //记录到response
            FastWriter writer;
            str = writer.write(data);
            response->setData(str);
            response->setStatusCode(StatusCode::OK);
            return true;
        }
        else if (m_method == "LOGIN") {
            response->setStatusCode(StatusCode::OK);
            return true;
        }
        else if (m_method == "ADD") {
      int ret=isAdmi(mysql);
            if (!ret) {
                response->setStatusCode(StatusCode::Illegal);
                return false;
            }
ret=isRepeat(mysql);
            if(ret) {
                response->setStatusCode(StatusCode::Repeat);
                return false;
            }
            char* tmp=(char*)calloc(1000,1);
              sprintf(tmp, "insert into data (name,id,chinese,math,english,uni,total) values ('%s','%s',%d,%d,%d,%d,%d);",
                m_name.c_str(), m_id.c_str(), m_chinese, m_math, m_english, m_uni, (m_uni +m_math +m_english + m_english));
            string str(tmp);

            if (!mysql->update(str)) {
                mysql->rollback();
                response->setStatusCode(StatusCode::Failure);
                return false;
            }

            //重新排序
            resort(mysql);


            //提交事务
            mysql->commit();
            response->setStatusCode(StatusCode::OK);
            return true;
        }
        else if (m_method == "DELETE") {
            if (!isAdmi(mysql)) {
                response->setStatusCode(StatusCode::Illegal);
                return false;
            }

            char* tmp=(char*)calloc(1000,1);
            int ret = sprintf(tmp, "delete from data where id='%s';", m_id.c_str());
            string str(tmp);
            mysql->update(str);

            if (!ret) {
                mysql->rollback();
                response->setStatusCode(StatusCode::Failure);
                return false;
            }

            //重新排序

            resort(mysql);
            //提交事务
            mysql->commit();
            response->setStatusCode(StatusCode::OK);
            return true;
        }
        else if (m_method == "MODIFY") {
            if (!isAdmi(mysql)) {
                response->setStatusCode(StatusCode::Illegal);
                return false;
            }

            char* tmp=(char*)calloc(1000,1);
             sprintf(tmp, "update data set name='%s',chinese=%d,math=%d,english=%d,uni=%d,total=%d where id='%s';",
                m_name.c_str(), m_chinese, m_math, m_english, m_uni, (m_uni +m_math +m_english + m_english), m_id.c_str());
            string str(tmp);
            int ret=mysql->update(str);
            if (!ret) {
                mysql->rollback();
                response->setStatusCode(StatusCode::Failure);
                return false;
            }

            //重新排序
            resort(mysql);

            //提交事务
            mysql->commit();
            response->setStatusCode(StatusCode::OK);
            return true;
        }
        else if(m_method=="ALL") {
            if (!isAdmi(mysql)) {
                response->setStatusCode(StatusCode::Illegal);
                return false;
            }
            char* tmp=(char*)calloc(1000,1);
            sprintf(tmp, "select id from data ;");
            string str(tmp);
            if(!mysql->query(str)) {
                response->setStatusCode(StatusCode::Failure);
                return false;
            }


            //用json记录返回数据
            Value result;
            while(mysql->next()) {

                result.append(mysql->value(0));
            }
            //记录到response
            FastWriter writer;
            str = writer.write(result);
            cout<<str;
            response->setData(str);
            response->setStatusCode(StatusCode::OK);
            return true;
        }

        else {
            response->setStatusCode(StatusCode::Failure);
            return false;
        }
    }
}

bool Request::isAdmi(MySqlConn*mysql){

    char* tmp=(char*)calloc(1000,1);
     sprintf(tmp, "select job from admini where account='%s';", m_account.c_str());
    string str(tmp);
    if(!mysql->query(str)) {
        return false;
    }

    if(!mysql->next()) {
        return false;
    }
    if (mysql->value(0) != "admi") {
        return false;
    }
    else return true;
  
}

bool Request::isUser(MySqlConn* mysql)
{

    char* tmp=(char*)calloc(1000,1);
     sprintf(tmp, "select passwd from admini where account='%s';", m_account.c_str());
    string str(tmp);

    if(!mysql->query(str)) {
        return false;
    }
    if(!mysql->next()) {
        return false;
    }

    if (mysql->value(0) != m_passwd) {
        return false;
    }
    else {

        return true;
    }
}

bool Request::isRepeat(MySqlConn *mysql) {
    char* tmp=(char*)calloc(1000,1);
    sprintf(tmp, "select name from data where id='%s';", m_id.c_str());
    string str(tmp);

    if(!mysql->query(str)) {
        return false;
    }
    if(!mysql->next()) {
        return false;
    }
else return true;
}

bool Request::isRepeate(MySqlConn *mysql) {
    char* tmp=(char*)calloc(1000,1);
    sprintf(tmp, "select passwd from admini where account='%s';", m_account.c_str());
    string str(tmp);

    if(!mysql->query(str)) {
        return false;
    }
    if(!mysql->next()) {
        return false;
    }
    else return true;
}

void Request::resort(MySqlConn*mysql) {
    //创建一个临时表计算排名
    mysql->update("CREATE TEMPORARY TABLE temp_rank AS SELECT id, RANK() OVER(ORDER BY total DESC) AS myrank FROM data; ");
    //更新排名
    mysql->update("UPDATE data JOIN temp_rank ON data.id = temp_rank.id SET data.myrank = temp_rank.myrank;");
    //删除临时表
    mysql->update("DROP TEMPORARY TABLE temp_rank;");
}





